
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.TexturePaint;
import java.awt.geom.GeneralPath;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

public class areaDibujo extends javax.swing.JPanel {

   
    private ArrayList<Point> coordenadas = new ArrayList<Point>();
    private ArrayList<Figuras> figuras = new ArrayList<Figuras>();
    private Color color;
    private boolean guardaDibujo;
    private Point inicioArrastre;
    private Point finArrastre;
    private GeneralPath trazoPolilinea = new GeneralPath();
    private boolean inicioPolilinea;
    private int anchoGrid;
    private boolean dibujandoPolilinea;
    private int grosor;
    private int indexestilo;
    private int indexrelleno;
    private boolean dibporCoordenadas;
    private boolean rellenarDibujo, dibManual, cerrarDibujo;

   
    public areaDibujo() {
        initComponents();
        color = Color.BLACK;//la figura por defecto en negro.       
        dibporCoordenadas = true;//por defecto se dibuja por coordenadas
        inicioPolilinea = false;
        anchoGrid = 100;
        dibujandoPolilinea = false;
        grosor = 1;//por defecto en ancho del trazo es de un pixel.


    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        grid(g);

        GeneralPath fig = new GeneralPath();
        Graphics2D g2d = (Graphics2D) g;


        if (figuras.size() > 0) {
            for (Figuras line : figuras) {
                g2d.setColor(line.getColor());

                if (line.getEstadoPath()) {
                    line.getGeneralPath().closePath();
                }
                
                
                switch (line.getEstiloLinea()) {//estilos de linea

                    case 0://sin estilo. 
                        g2d.setStroke(new BasicStroke(line.getGrosorTrazo()));
                        break;
                    case 1://estilo con 20-10-20
                        float guiones[] = {20.0f, 10.0f, 20.0f};
                        BasicStroke pincel = new BasicStroke(line.getGrosorTrazo(), BasicStroke.JOIN_ROUND, BasicStroke.JOIN_MITER, 13f, guiones, 13f);
                        g2d.setStroke(pincel);
                        break;

                    case 2://estulo con 35-8-35
                        float lin[] = {35.0f, 8.6f, 35.0f};
                        pincel = new BasicStroke(line.getGrosorTrazo(), BasicStroke.JOIN_ROUND, BasicStroke.JOIN_MITER, 10f, lin, 10f);
                        g2d.setStroke(pincel);
                        break;

                }//para establecer un estilo de linea.....


               
                switch (line.getEstiloRelleno()) {//dibujar con estilos de relleno y parametros antes definidos

                    case 0://sin relleno
                        g2d.draw(line.getGeneralPath());
                        break;
                    case 1://relleno solido
                        g2d.fill(line.getGeneralPath());
                                        
                        break;

                    case 2://relleno con gradientes
                        
                        g2d.setPaint(new GradientPaint(90, 80, Color.GREEN,
                                95, 100, Color.MAGENTA, true));
                        g2d.fill(line.getGeneralPath());
                        
                        break;

                    case 3://relleneo con texturas.
                        BufferedImage imagenBuf = new BufferedImage(10, 10, BufferedImage.TYPE_INT_RGB);
                        Graphics2D gg = imagenBuf.createGraphics();
                        gg.setColor(Color.BLUE);
                        gg.fillRect(2, 2, 10, 10);
                        gg.setColor(Color.MAGENTA);
                        gg.drawRect(2, 2, 6, 6);
                        gg.setColor(Color.PINK);
                        gg.fillRect(1, 1, 4, 4);
                        gg.setColor(Color.RED);
                        gg.drawRect(2, 2, 3, 3);

                        g2d.setPaint(new TexturePaint(imagenBuf, new Rectangle(10, 10)));
                        g2d.fill(line.getGeneralPath());
                                               
                        break;

                }//fin de dibujo con relleno y parametros guardados.

            }//fin for q imprime figuras del ArrayList
        }//fin de if.

        g2d.setStroke(new BasicStroke(grosor));
        g2d.setColor(color);


        switch (indexestilo) {

            case 0:
                g2d.setStroke(new BasicStroke(grosor));
                break;
            case 1:
                float guiones[] = {20.0f, 10.0f, 20.0f};
                BasicStroke pincel = new BasicStroke(grosor, BasicStroke.JOIN_ROUND, BasicStroke.JOIN_MITER, 13f, guiones, 13f);
                g2d.setStroke(pincel);
                break;

            case 2:
                float lin[] = {35.0f, 8.6f, 35.0f};
                pincel = new BasicStroke(grosor, BasicStroke.JOIN_ROUND, BasicStroke.JOIN_MITER, 10f, lin, 10f);
                g2d.setStroke(pincel);
                break;

        }
        
        //aqui podemos empezar a dibujar.
        

        switch (indexrelleno) {

            case 0:
                g2d.setPaint(color);
                break;
            case 1:
                g2d.setPaint(color);
                break;

            case 2:
                g2d.setPaint(new GradientPaint(90, 80, Color.GREEN,
                        95, 100, Color.MAGENTA, true));
                //g2d.fill(fig);

                break;

            case 3:
                BufferedImage imagenBuf = new BufferedImage(10, 10, BufferedImage.TYPE_INT_RGB);
                Graphics2D gg = imagenBuf.createGraphics();
                gg.setColor(Color.BLUE);
                gg.fillRect(2, 2, 10, 10);
                gg.setColor(Color.MAGENTA);
                gg.drawRect(2, 2, 6, 6);
                gg.setColor(Color.PINK);
                gg.fillRect(1, 1, 4, 4);
                gg.setColor(Color.RED);
                gg.drawRect(2, 2, 3, 3);

                g2d.setPaint(new TexturePaint(imagenBuf, new Rectangle(10, 10)));
                // g2d.fill(fig);
                break;

        }
        

        if (dibporCoordenadas) {

            if (coordenadas.size() > 0) {//si el arreglo tiene algo.
                g.setColor(Color.gray);
                g.drawString("("+coordenadas.get(0).x+","+coordenadas.get(0).y+")",coordenadas.get(0).x,coordenadas.get(0).y);
                fig.moveTo(coordenadas.get(0).x,coordenadas.get(0).y);
                g.setColor(color);
                    
                for (int i = 1; i < coordenadas.size(); i++) {
                    g.setColor(Color.gray);
                    g.drawString("("+coordenadas.get(i).x+","+coordenadas.get(i).y+")",coordenadas.get(i).x,coordenadas.get(i).y);
                    g.setColor(color);
                    
                    fig.lineTo(coordenadas.get(i).x,coordenadas.get(i).y);
                }//fin de trazos guardados en el arreglo.


                if (indexestilo > 1) {
                    g2d.fill(fig);
                } else {
                    g2d.draw(fig);

                }
                
         guardarDibujo(fig, g2d);
               

            }//en el arreglo tengo a un path...TRAZO EL PATH,ESTABLEZCO OLOR Y DIBUJO EN EL FRAME.
            /**
             * *****SOLO Y SOLO SI jRBDibujoCoordenadas.isSelected();********
             */
        }

        if (dibManual) {

            //*********************revisar esto, si ya se cierra aqui, ya no es necesario hacerlo en foreach
            if (cerrarDibujo && guardaDibujo == true) {//el path se cierra si ya se va a guardar
                trazoPolilinea.closePath();//guarda el estado de la figura.
                

                if (indexrelleno > 1) {
                    g2d.fill(trazoPolilinea);
                } else {
                    g2d.draw(trazoPolilinea);
                }
            }

            g2d.draw(trazoPolilinea);
            
            if(dibujandoPolilinea)
            g2d.drawLine((int) inicioArrastre.getX(), (int) inicioArrastre.getY(), (int) finArrastre.getX(), (int) finArrastre.getY());
        
            
         guardarDibujo(trazoPolilinea, g2d);
        }
        

       // fig = null;

    }

    private void guardarDibujo(GeneralPath fig, Graphics2D g2d) {

        if (guardaDibujo) {
            Figuras miDibActual = new Figuras(fig, g2d, grosor, rellenarDibujo, cerrarDibujo, indexrelleno, indexestilo);
            figuras.add(miDibActual);
            guardaDibujo = false;
          
            
            
            repaint();

        }

    }

    public void grid(Graphics g) {


        for (int i = 0; i < this.getBounds().width;) {  //medida en X  
            g.drawString("" + (i), i, 10);
            i += anchoGrid;
        }
        for (int j = 10; j < this.getBounds().height;) {//medida en Y
            if (j != 10) {
                g.drawString("" + (j - 10), 0, j);
            }
            j += anchoGrid;
        }


        g.setColor(new Color(218, 218, 218));
        for (int i = 0; i < this.getBounds().width;) {//lineas verticales
            g.drawLine(i, 0, i, this.getBounds().width);
            i += 100;
        }
        for (int j = 0; j < this.getBounds().width;) {//lineas horizontales
            g.drawLine(0, j, this.getBounds().width, j);//(x0,y0,x1,y1);
            j += 100;
        }
        //***************SE HA DIBUJADO EL GRID******************

    }
    
    
    public void setInicioPolilinea(boolean estadoInicioPolilinea){
        inicioPolilinea = estadoInicioPolilinea;
    }
    
    public ArrayList<Point> getArrayListCoordenadas(){
        return coordenadas;
    }
    public void setdibCoordenadas(boolean estadoDibujoPorCoordenadas) {
        dibporCoordenadas = estadoDibujoPorCoordenadas;
    }

    

    public void setcerrarDibujo(boolean estadoCloseDibujo) {
        cerrarDibujo = estadoCloseDibujo;
    }

    public boolean getCerrarDibujo() {
        return cerrarDibujo;
    }

    public void setRellenarDibujo(boolean estadoRellenoDibujo) {
        rellenarDibujo = estadoRellenoDibujo;
    }

    public boolean getRellenoDibujo() {
        return rellenarDibujo;
    }

    public void setGuardaDibujo(boolean estadoGuardaDibujo) {
        guardaDibujo = estadoGuardaDibujo;
    }

    public boolean getGuardaDibujo() {
        return guardaDibujo;
    }

    public void setDibujando(boolean estadoDibujando) {
        dibujandoPolilinea = estadoDibujando;
    }

    public boolean getDibujando() {
        return dibujandoPolilinea;
    }

    public void setDibujoManual(boolean estadoDibujoManual) {
        dibManual = estadoDibujoManual;
    }

    public boolean getDibujoManual() {
        return dibManual;
    }

    public ArrayList<Figuras> getArrListFiguras() {
        return figuras;
    }

    public GeneralPath getTrazoPolilinea() {
        return trazoPolilinea;
    }

    public void setColor(Color valorColor) {
        color = valorColor;
    }

    public Color getColor() {
        return color;
    }

    public void setGrosor(int valGrosor) {
        grosor = valGrosor;
    }

    public int getGrosor() {
        return grosor;
    }

    public void setIndexEstilo(int valIndexEstilo) {
        indexestilo = valIndexEstilo;
    }

    public int getIndexEstilo() {
        return indexestilo;
    }

    public void setIndexRelleno(int valIndexRelleno) {
        indexrelleno = valIndexRelleno;
    }

    public int getIndexRelleno() {
        return indexrelleno;
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                formMouseClicked(evt);
            }
            public void mousePressed(java.awt.event.MouseEvent evt) {
                formMousePressed(evt);
            }
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                formMouseReleased(evt);
            }
        });
        addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                formMouseDragged(evt);
            }
            public void mouseMoved(java.awt.event.MouseEvent evt) {
                formMouseMoved(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 400, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 300, Short.MAX_VALUE)
        );
    }// </editor-fold>//GEN-END:initComponents

    private void formMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseClicked
        // TODO add your handling code here:
        if(dibManual){//ESTA EN MODO MANUAL
        
        if (evt.getClickCount() == 1) {//si ocurre un clic

            inicioArrastre = new Point(evt.getX(), evt.getY());
            finArrastre = inicioArrastre;
            dibujandoPolilinea = true;//para ir actualizando el punto fin del dibujo y redibujar la linea. Con mouse move event

            if (inicioPolilinea) {//creas un nuevo gp inicias el trazo y sales.
                trazoPolilinea = new GeneralPath();
                trazoPolilinea.moveTo(evt.getX(), evt.getY());
                inicioPolilinea = false;
              
            } else {

                trazoPolilinea.lineTo(evt.getX(), evt.getY());

            }
            
        } //fin de si ocurre un clic
        
        else {//si el el contador de clic es > 1

            inicioPolilinea = true;
            dibujandoPolilinea = false;
            guardaDibujo = true;

            repaint();
        }
        
        }//dibujo en modo manual
    }//GEN-LAST:event_formMouseClicked

    private void formMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseReleased
        // TODO add your handling code here:
    }//GEN-LAST:event_formMouseReleased

    private void formMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMousePressed
        // TODO add your handling code here:
    }//GEN-LAST:event_formMousePressed

    private void formMouseMoved(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseMoved
        // TODO add your handling code here:

        //si se da click en dibujo manual
        if (dibujandoPolilinea && dibManual) {
            finArrastre = new Point(evt.getX(), evt.getY());
            repaint();
        }


    }//GEN-LAST:event_formMouseMoved

    private void formMouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseDragged
        // TODO add your handling code here:
    }//GEN-LAST:event_formMouseDragged
    // Variables declaration - do not modify//GEN-BEGIN:variables
    // End of variables declaration//GEN-END:variables
}
